package cn.wolfcode.luowowo.service.impl;

import cn.wolfcode.luowowo.domain.Destination;
import cn.wolfcode.luowowo.domain.Strategy;
import cn.wolfcode.luowowo.domain.StrategyCatalog;
import cn.wolfcode.luowowo.query.QueryObject;
import cn.wolfcode.luowowo.repository.StrategyCatalogRepository;
import cn.wolfcode.luowowo.repository.StrategyRepository;
import cn.wolfcode.luowowo.service.IDestinationService;
import cn.wolfcode.luowowo.service.IStrategyCatalogService;
import cn.wolfcode.luowowo.service.IStrategyService;
import cn.wolfcode.luowowo.util.DBHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.GroupOperation;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class StrategyCatalogServiceImpl implements IStrategyCatalogService {
    @Autowired
    private StrategyCatalogRepository strategyCatalogRepository;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IDestinationService destinationService;

    @Autowired
    private StrategyRepository strategyRepository;

    @Override
    public void insert(StrategyCatalog strategyCatalog) {
        strategyCatalog.setId(null);
        Destination destination = destinationService.select(strategyCatalog.getDestId());
        strategyCatalog.setDestName(destination.getName());
        strategyCatalogRepository.save(strategyCatalog);
    }

    @Override
    public void update(StrategyCatalog strategyCatalog) {
        Destination destination = destinationService.select(strategyCatalog.getDestId());
        strategyCatalog.setDestName(destination.getName());
        strategyCatalogRepository.save(strategyCatalog);
    }

    @Override
    public void delete(String id) {
        strategyCatalogRepository.deleteById(id);
    }

    @Override
    public StrategyCatalog select(String id) {
        return strategyCatalogRepository.findById(id).get();
    }

    @Override
    public Page<StrategyCatalog> query(QueryObject qo) {
        Query query = new Query();

        PageRequest pageable = PageRequest.of(qo.getCurrentPage() - 1, qo.getPageSize()
                , Sort.Direction.ASC, "_id");

        return DBHelper.query(mongoTemplate, StrategyCatalog.class, query, pageable);
    }

    @Override
    public List<StrategyCatalog> listAll() {
        return strategyCatalogRepository.findAll();
    }

    @Override
    public List<StrategyCatalog> listAllGroup() {
        GroupOperation group = Aggregation.group("destName")
                .addToSet("$destName")
                .as("destName");
        TypedAggregation<StrategyCatalog> typedAggregation = Aggregation.newAggregation(StrategyCatalog.class, group);
        AggregationResults<StrategyCatalog> aggregationResults = mongoTemplate.aggregate(typedAggregation, StrategyCatalog.class);
        List<StrategyCatalog> list = aggregationResults.getMappedResults();
//        list.forEach(System.err::println);
        for (StrategyCatalog sc : list) {
            List<StrategyCatalog> mls = strategyCatalogRepository.findByDestNameOrderBySequenceAsc(sc.getDestName());
            sc.setMapList(mls);
        }
        return list;
    }

    @Override
    public List<StrategyCatalog> queryByDestId(String destId) {
        List<StrategyCatalog> catalogs = strategyCatalogRepository.findByDestId(destId);
        for (StrategyCatalog catalog : catalogs) {
            List<Strategy> strategies = strategyRepository.findByCatalogId(catalog.getId());
            catalog.setStrategies(strategies);
        }
        return catalogs;
    }
}
